﻿using Coldairarrow.Business.PB;
using Coldairarrow.Business.TD;
using Coldairarrow.Entity.TD;
using Coldairarrow.IBusiness.DTO;
using Coldairarrow.Util;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Quartz.Util;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Coldairarrow.IBusiness;
using Coldairarrow.Business.IT;
using Coldairarrow.Entity.PB;
using Coldairarrow.Entity.DTO;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.SS.Util;

namespace Coldairarrow.Api.Controllers.TD
{
    [Route("/TD/[controller]/[action]")]
    public class TD_OutStorageController : BaseApiController
    {
        #region DI

        public TD_OutStorageController(ITD_OutStorageBusiness tD_OutStorageBus, IServiceProvider provider, IOperator op, IServiceProvider svcProvider)
        {
            _tD_OutStorageBus = tD_OutStorageBus;
            _provider = provider;
            _Op = op;
            this.serviceProvider = svcProvider;
        }

        ITD_OutStorageBusiness _tD_OutStorageBus { get; }

        IServiceProvider _provider { get; }

        IOperator _Op { get; }

        IServiceProvider serviceProvider { get; }

        #endregion

        #region 获取

        [HttpPost]
        public async Task<PageResult<TD_OutStorageDTO>> GetDataList(TD_OutStoragePageInput input)
        {
            return await _tD_OutStorageBus.GetDataListAsync(input);
        }


        /// <summary>
        /// 获取发货明细信息
        /// </summary>
        /// <param name="ParentId"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<TD_OutStorageInfo> GetTD_OutStorageinfo(string ParentId) {
            return await _tD_OutStorageBus.GetTD_OutStorageinfo(ParentId);
        }


        /// <summary>
        /// 获取发货出库类型数据
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<PageResult<TD_OutStorage>> GetDataListAsyncGroup(TD_OutStoragePageInput input) { 
            return await _tD_OutStorageBus.GetDataListAsyncGroup(input);
        }
        /// <summary>
        /// 获取报废出库类型数据
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<PageResult<TD_OutStorage>> GetDataListAsyncScrap(TD_OutStoragePageInput input)
        {
            return await _tD_OutStorageBus.GetDataListAsyncScrap(input);
        }
        [HttpPost]
        public async Task<TD_OutStorage> GetTheData(IdInputDTO input)
        {
            return await _tD_OutStorageBus.GetTheDataAsync(input.id);
        }

        /// <summary>
        /// 根据出库ID查询出库明细
        /// </summary>
        /// <param name="input">出库ID</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<TD_OutStorageViewDTO> GetTheDatas(IdInputDTO input)
        {
            return await _tD_OutStorageBus.GetTheDataAsyncs(input.id);
        }

        /// <summary>
        /// 大屏显示当月生产领料吨数
        /// </summary>
        /// <param name="Month">前第几月</param>
        /// <returns>当月生产领料吨数</returns>
        [HttpPost]
        [NoCheckJWT]
        public ScreenDisplayValueDTO GetMonthProductOut(int Month=0)
        {
            return _tD_OutStorageBus.GetMonthProductOut(Month);
        }
        #endregion

        #region 提交

        [HttpPost]
        public async Task SaveData(TD_OutStorage data)
        {
            if (data.Id.IsNullOrEmpty())
            {
                InitEntity(data);
                data.StorageId = _Op.Property.DefaultStorageId;
                foreach (var item in data.OutStorDetails)
                {
                    InitEntity(item);
                    item.OutStorId = data.Id;
                    item.TotalAmt = item.Price * item.LocalNum;
                }
                await _tD_OutStorageBus.AddDataAsync(data);
            }
            else
            {
                foreach (var item in data.OutStorDetails)
                {
                    if (item.Id.StartsWith("newid_"))
                        InitEntity(item);
                    item.OutStorId = data.Id;
                    item.TotalAmt = item.Price * item.LocalNum;
                }
                await _tD_OutStorageBus.UpdateDataAsync(data);
            }
        }
        /// <summary>
        /// 获取项目汇总数据
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<PageResult<ProjectSummaryDTO>> GetInventoryData(PageInput<ProjectSummaryContionDTO> input)
        {
            return await _tD_OutStorageBus.GetProjectSummary(input);
        }
        /// <summary>
        /// 获取出库汇总信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<PageResultData<OutStoreDetail>> OutStoreDetailList(PageInput<ProjectSummaryContionDTO> input)
        {
            return await _tD_OutStorageBus.OutStoreDetail(input);
        }
        [HttpPost]
        public async Task DeleteData(List<string> ids)
        {
            await _tD_OutStorageBus.DeleteDataAsync(ids);
        }

        /// <summary>
        /// 出库审核
        /// </summary>
        /// <param name="audit"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task Audit(AuditDTO audit)
        {
            audit.StorId = _Op.Property.DefaultStorageId;
            audit.AuditUserId = _Op.UserId;
            audit.AuditTime = DateTime.Now;
            if (audit.AuditType == AuditType.Approve)
                await _tD_OutStorageBus.Approve(audit);
            else
                await _tD_OutStorageBus.Reject(audit);
        }
        /// <summary>
        /// 出库审核
        /// </summary>
        /// <param name="audit"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task OutAudit(AuditDTO audit)
        {
            audit.StorId = _Op.Property.DefaultStorageId;
            audit.AuditUserId = _Op.UserId;
            audit.AuditTime = DateTime.Now;
            if (audit.AuditType == AuditType.Approve)
                await _tD_OutStorageBus.OutApprove(audit);
            else
                await _tD_OutStorageBus.OutReject(audit);
        }
        /// <summary>
        /// 空托盘出库
        /// </summary>
        /// <param name="listTray"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<AjaxResult> OutBlankTray(List<KeyValuePair<string, string>> listTray)
        {
            return await _tD_OutStorageBus.OutBlankTray(listTray, _Op.Property.DefaultStorageId);
        }

        /// <summary>
        /// 自动出库
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<AjaxResult<TD_OutStorage>> AutoOut(AutoOutStorageQM data)
        {
            var materialSvc = this._provider.GetRequiredService<IPB_MaterialBusiness>();
            var material = await materialSvc.GetByBarcode(data.MaterialCode);
            if (material == null) return new AjaxResult<TD_OutStorage>() { Success = false, Msg = "物料编码不正确" };
            var StorId = _Op.Property.DefaultStorageId;
            var reqData = new ReqMaterialQM() { StorId = StorId, MaterialId = material.Id, BatchNo = data.BatchNo, Num = data.Num };
            var listOut = await this._tD_OutStorageBus.ReqMaterial(reqData);
            if (!listOut.Success) return new AjaxResult<TD_OutStorage>() { Success = false, Msg = listOut.Msg };

            var entity = new TD_OutStorage()
            {
                SendId = data.SendId,
                StorageId = StorId,
                OutTime = DateTime.Now,
                OutType = "ProductOut",
                OutNum = data.Num,
                Status = 0,
                OutStorDetails = new List<TD_OutStorDetail>()
            };
            InitEntity(entity);
            foreach (var detail in listOut.Data)
            {
                var item = new TD_OutStorDetail()
                {
                    StorId = StorId,
                    OutStorId = entity.Id,
                    LocalId = detail.LocalId,
                    RackId = detail.RackId,
                    AreaId = detail.AreaId,
                    MaterialId = detail.MaterialId,
                    BatchNo = detail.BatchNo,
                    LocalNum = detail.LocalNum,
                    OutNum = detail.OutNum,
                    Price = material.Price.GetValueOrDefault(0),
                    TotalAmt = material.Price.GetValueOrDefault(0) * detail.OutNum
                };
                InitEntity(item);
                entity.OutStorDetails.Add(item);
            }
            await _tD_OutStorageBus.AddDataAsync(entity);
            return new AjaxResult<TD_OutStorage>() { Success = true, Msg = "出库成功", Data = entity };
        }

        /// <summary>
        /// 手动出库
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<AjaxResult<TD_OutStorage>> ManualOut(ManualOutStorageQM data)
        {
            var materialSvc = this._provider.GetRequiredService<IPB_MaterialBusiness>();
            var material = await materialSvc.GetByBarcode(data.MaterialCode);
            if (material == null) return new AjaxResult<TD_OutStorage>() { Success = false, Msg = "物料编码不正确" };
            var StorId = _Op.Property.DefaultStorageId;

            var entity = new TD_OutStorage()
            {
                SendId = data.SendId,
                StorageId = StorId,
                OutTime = DateTime.Now,
                OutType = "ProductOut",
                OutNum = data.Num,
                Status = 0,
                OutStorDetails = new List<TD_OutStorDetail>()
            };
            InitEntity(entity);

            var localSvc = this._provider.GetRequiredService<IPB_LocationBusiness>();
            var local = await localSvc.GetByCode(StorId, data.LocalCode);
            if (local == null) return new AjaxResult<TD_OutStorage>() { Success = false, Msg = "货位编码不正确" };

            var item = new TD_OutStorDetail()
            {
                StorId = StorId,
                OutStorId = entity.Id,
                LocalId = local.Id,
                MaterialId = material.Id,
                BatchNo = data.BatchNo,
                LocalNum = data.Num,
                OutNum = data.Num,
                Price = material.Price.GetValueOrDefault(0),
                TotalAmt = material.Price.GetValueOrDefault(0) * data.Num
            };
            InitEntity(item);
            entity.OutStorDetails.Add(item);

            await _tD_OutStorageBus.AddDataAsync(entity);
            return new AjaxResult<TD_OutStorage>() { Success = true, Msg = "出库成功", Data = entity };
        }


        //入库汇总导出
        [HttpGet]
        public async Task<IActionResult> GetReceiptSummaryExport(string MaterialNameOrCode, string ProjectName, DateTime? OrderTimeStart, DateTime? OrderTimeEnd, string StrareaName)
        {
            //输入搜索条件
            PageInput<ProjectSummaryContionDTO> input = new PageInput<ProjectSummaryContionDTO>();
            input.Search.MaterialNameOrCode = MaterialNameOrCode;
            input.Search.ProjectName = ProjectName;
            input.Search.OrderTimeStart = OrderTimeStart;
            input.Search.OrderTimeEnd = OrderTimeEnd;
            input.Search.StrareaName = StrareaName;

            //查询数据
            var listFaultInfo = await _tD_OutStorageBus.OutStoreDetail(input);
            //二：代码创建一个Excel表格（这里称为工作簿）
            //创建Excel文件的对象 工作簿(调用NPOI文件)
            HSSFWorkbook excelBook = new HSSFWorkbook();
            //创建Excel工作表 Sheet=故障码信息
            //标题
            ISheet sheet1 = excelBook.CreateSheet("入库汇总导出");
            sheet1.AddMergedRegion(new CellRangeAddress(0, 0, 0, 7));//合并单元格,4个参数依次为为startRow,endRow,startCol,endCo
            IRow ROW = sheet1.CreateRow(0);
            ICellStyle cellStyle = excelBook.CreateCellStyle();
            cellStyle.DataFormat = HSSFDataFormat.GetBuiltinFormat("_ * #,##0.00_ ;_ * -#,##0.00_ ;_ * \"-\"??_ ;_ @_ ");

            Double? TotalStockin = 0;
            Double? TotalWarehousingamount = 0;
            for (int i = 0; i < listFaultInfo.Data.Count; i++)
            {
                TotalStockin += listFaultInfo.Data[i].OutNums;
                TotalWarehousingamount += listFaultInfo.Data[i].materialWeight;
            }
            ROW.CreateCell(0).SetCellValue($"出库总数:{TotalStockin}      出库总额:{TotalWarehousingamount} ");
            IRow row5Temp = sheet1.CreateRow(1);
            row5Temp.CreateCell(0).SetCellValue("仓库");
            row5Temp.CreateCell(1).SetCellValue("编号");
            row5Temp.CreateCell(2).SetCellValue("名称");
            row5Temp.CreateCell(3).SetCellValue("规格");
            row5Temp.CreateCell(4).SetCellValue("出库数量");
            row5Temp.CreateCell(5).SetCellValue("出库重量(kg)");
            row5Temp.CreateCell(6).SetCellValue("单重");
            //给Sheet(清单信息）添加第一行的头部标题
            IRow row1 = sheet1.CreateRow(6);

            for (int i = 0; i < listFaultInfo.Data.Count; i++)
            {

                //sheet1.CreateRow(i).
                //创建行
                IRow rowTemp = sheet1.CreateRow(i + 2);
                rowTemp.Height = 600;

                //出库仓库
                rowTemp.CreateCell(0).SetCellValue(listFaultInfo.Data[i].Warehouse);
                //物料编号
                rowTemp.CreateCell(1).SetCellValue(listFaultInfo.Data[i].materialCode);



                //物料名称
                rowTemp.CreateCell(2).SetCellValue(listFaultInfo.Data[i].MaterName);

                //单位
                rowTemp.CreateCell(3).SetCellValue(listFaultInfo.Data[i].materialSpce);
                //出库数量
                rowTemp.CreateCell(4).SetCellValue(Convert.ToDouble(listFaultInfo.Data[i].OutNums));
                //物料理论重量
                rowTemp.CreateCell(5).SetCellValue(Convert.ToDouble(listFaultInfo.Data[i].materialWeight.ToString()));

                //单价
                rowTemp.CreateCell(6).SetCellValue(Convert.ToDouble(listFaultInfo.Data[i].Weight.ToString()));


         
            }
            //输出的文件名称
            string fileName = "出库汇总导出" + DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss-ffff") + ".xls";
            //把Excel转为流，输出
            //创建文件流
            System.IO.MemoryStream bookStream = new System.IO.MemoryStream();
            //将工作薄写入文件流
            excelBook.Write(bookStream);

            //输出之前调用Seek（偏移量，游标位置) 把0位置指定为开始位置
            bookStream.Seek(0, System.IO.SeekOrigin.Begin);
            //Stream对象,文件类型,文件名称
            return File(bookStream, "application/vnd.ms-excel", fileName);
        }
        #endregion
    }
}